/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extension.room.analyse;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import log.Debug;

/**
 *
 * @author daz
 */
public class ChooseBlockCardTienlen {

    private static LinkedList<CardSet> listCardSets;
    private static Random random = new Random();

    public static void main(String[] args) {
        CardDealer dealer = new CardDealer();
        dealer.shuffleCard();
        int numberCard = 13;
        int[] listCards = new int[numberCard];
        for (int i = 0; i < numberCard; i++) {
            listCards[i] = dealer.nextCard();
        }
        for (Integer card : listCards) {
            Debug.n(Card.getName(card));
        }
        listCardSets = new LinkedList<CardSet>();

        extractSpecialFlush(listCards);
        extractSpecialPair(listCards);
        Debug.d("=====================");
        Debug.d("set size :" + listCardSets.size());
        for (CardSet s : listCardSets) {
            Debug.n(s.getTypeName() + ":" + s.toString());
            Debug.d("");
        }
//        testBlockPair();
//        testBlockFlush();
    }

    private static void testBlockPair() {
        CardSet setFight = new CardSet(CardSetTestTienlen.getCardSet2(), CardSet.PAIR);
        List<Integer> listBlock = chooseBlockCard(setFight);
        Debug.d("list block :" + listBlock.toString());
    }

    private static void testBlockFlush() {
        int[] cardIds = new int[3];
        cardIds[0] = random.nextInt(100) % 52;
        for (int i = 1; i < cardIds.length; i++) {
            cardIds[i] = (cardIds[0] + i) % 52;
        }
        CardSet setFight = new CardSet(CardSetTestTienlen.getCardSet4(), CardSet.FLUSH);
//        CardSet setFight = new CardSet(cardIds, CardSet.FLUSH);
        List<Integer> listBlock = chooseBlockCard(setFight);
        Debug.d("list block :" + listBlock.toString());
    }

    private static void testBlockOneCard(int[] listCards) {
        chooseBlockCard(random.nextInt(52), listCards);
    }

    private static void testBlock2(int[] listCards) {
        chooseBlockCard(40, listCards);
    }

    private static void testBlock2By4OfKind(int[] listCards) {
        chooseBlockCard(40);
    }

    private static int getCardValue(int cardId) {
        return (cardId - 2 + 13) % 13;
    }

    private static List<Integer> chooseBlockCard(int cardFight) {
        //chan 2
        List<Integer> listBlock = new LinkedList<Integer>();
        for (CardSet set : listCardSets) {
            if (set.getSetSize() == 4 && set.getType() == CardSet.PAIR) {
                Debug.d("set :" + set.toString());
                listBlock.addAll(set.getListCards());
                break;
            }
        }
        return listBlock;

    }

    private static List<Integer> chooseBlockCard(CardSet setFight) {
        // chan bo
        List<Integer> listBlock = new LinkedList<Integer>();
        Debug.d("set fight :" + setFight.toString());
        for (CardSet set : listCardSets) {
            if (set.getType() == setFight.getType()
                    && set.getSetSize() >= setFight.getSetSize()) {
                listBlock.clear();
                if (set.getType() == CardSet.PAIR) {
                    boolean isChoose = true;
                    if (getCardValue(set.getCardId(0)) < getCardValue(setFight.getCardId(0))) {
                        isChoose = false;
                    } else if (set.getCardId(0) % 13 != 1) {
                        int startIndex = 0;
                        for (int i = 0; i < setFight.getSetSize(); i++) {
                            if (setFight.getCardId(0) / 13 == set.getCardId(i) / 13) {
                                startIndex = i;
                                break;
                            }
                        }
                        for (int i = startIndex; i < setFight.getSetSize(); i++) {
                            if (set.getCardId(i) / 13 != setFight.getCardId(i - startIndex) / 13) {
                                isChoose = false;
                                break;
                            }
                            listBlock.add(set.getCardId(i));
                        }
                    } else if (set.getCardId(0) % 13 == 1) {
                        for (int i = 0; i < setFight.getSetSize(); i++) {
                            listBlock.add(set.getCardId(i));
                        }
                    }
                    if (isChoose) {
                        Debug.d("set :" + set.toString());
                        return listBlock;
                    }
                } else {
                    int suit1 = set.getCardId(0) / 13;
                    int suit2 = setFight.getCardId(0) / 13;
                    if (suit1 == suit2) {
                        int startIndex = 0;
                        for (int i = 0; i < set.getSetSize(); i++) {
                            if (getCardValue(setFight.getCardId(0)) <= getCardValue(set.getCardId(i))) {
                                startIndex = i;
                                break;
                            }
                        }
                        if (set.getSetSize() - startIndex >= setFight.getSetSize()) {
                            boolean isChoose = true;
                            for (int i = startIndex; i < startIndex + setFight.getSetSize(); i++) {
                                listBlock.add(set.getCardId(i));
                                if (getCardValue(set.getCardId(i)) < getCardValue(setFight.getCardId(i - startIndex))) {
                                    isChoose = false;
                                    break;
                                }
                            }
                            if (isChoose) {
                                Debug.d("set :" + set.toString());
                                return listBlock;
                            }
                        }

                    }
                }

            }
        }
        listBlock.clear();
        return listBlock;
    }

    private static int chooseBlockCard(int cardFight, int[] listCards) {
        //chan 1 con
        int numberCards = listCards.length;
        int minBlockCard = -1;
        if (cardFight % 13 == 0) {
            for (int i = 0; i < numberCards; i++) {
                if (listCards[i] % 13 == 1) {
                    if (minBlockCard == -1 || minBlockCard / 13 < listCards[i] / 13) {
                        minBlockCard = listCards[i];
                    }
                }
            }
        } else if (cardFight % 13 == 1) {
            for (int i = 0; i < numberCards; i++) {
                if (listCards[i] % 13 == 1 && listCards[i] / 13 < cardFight / 13) {
                    if (minBlockCard == -1 || minBlockCard / 13 < listCards[i] / 13) {
                        minBlockCard = listCards[i];
                    }
                }
            }
        } else {
            for (int i = 0; i < numberCards; i++) {
                if ((cardFight / 13 == listCards[i] / 13
                        && getCardValue(cardFight) < getCardValue(listCards[i]))
                        || listCards[i] % 13 == 1) {
                    if (minBlockCard == -1 || getCardValue(listCards[i]) < getCardValue(minBlockCard)) {
                        minBlockCard = listCards[i];
                    }
                }
            }
        }

        Debug.d("");
        Debug.d("card fight id :" + cardFight);
        Debug.d("card fight :" + Card.getName(cardFight));
        if (minBlockCard != -1) {
            Card.showName(minBlockCard);
        }
        return minBlockCard;
    }

    private static void extractFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] / 13 > listCards[j] / 13
                        || (listCards[i] / 13 == listCards[j] / 13
                        && (listCards[i] - 2 + 13) % 13 > (listCards[j] - 2 + 13) % 13)) {
                    swap(i, j, listCards);
                }
            }
        }
        printListCardId(listCards);
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int cardId = (listCards[i] - 2 + 13) % 13;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId + (j - i) == (listCards[j] - 2 + 13) % 13 && listCards[i] / 13 == listCards[j] / 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
//            Debug.d("day :" + step);
            if (step != 0) {
                int[] flsush = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    flsush[k - i] = listCards[k];
                }
                if (step >= 2) {
                    CardSet flushSet = new CardSet(flsush, CardSet.FLUSH);
                    listCardSets.add(flushSet);
                }
                i = i + step;
            }
        }
    }

    private static int getCardRank(int cardId) {
        return (cardId - 2 + 13) % 13;
    }

    private static void extractSpecialFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                int rank1 = getCardRank(listCards[i]);
                int rank2 = getCardRank(listCards[j]);
                if (rank1 > rank2) {
                    swap(i, j, listCards);
                } else if (rank1 == rank2
                        && (listCards[i] / 13 > listCards[j] / 13)) {
                    swap(i, j, listCards);
                }
            }
        }
        printListCardId(listCards);
        Debug.d("");
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int numberSameValue = 0;
            int cardId = (listCards[i] - 2 + 13) % 13;
            for (int j = i + 1; j < numberCards; j++) {
                int cardRankCheck = getCardRank(listCards[j]);
                if (cardId + (j - i) - numberSameValue == cardRankCheck) {
                    step++;
                } else if (cardId + (j - i) - 1 - numberSameValue == cardRankCheck) {
                    numberSameValue++;
                } else {
                    j = numberCards;
                }
            }
            if (step >= 2) {
                int[] flush = new int[step + 1];
                int rankStart = getCardRank(listCards[i]);
                int delta = 0;
                for (int k = i; k <= i + step + numberSameValue; k++) {
                    int rankNext = getCardRank(listCards[k]);
                    if (rankNext == rankStart + k - i - delta) {
                        flush[k - i - delta] = listCards[k];
//                        Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                    } else if (rankNext == rankStart + k - i - 1 - delta) {
                        delta++;
                    }
                }
                CardSet flushSet = new CardSet(flush, CardSet.FLUSH);
                listCardSets.add(flushSet);
                i = i + step + numberSameValue;
            }
        }

    }

    private static void extractPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13
                        || (listCards[i] % 13 == listCards[j] % 13 && listCards[i] / 13 < listCards[j] / 13)) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }
        //tim phom ngang
        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    if (j < numberCards - 1 && cardId % 13 == listCards[j + 1] % 13) {
                        if (j < numberCards - 2 && cardId % 13 == listCards[j + 2] % 13) {
                            step = 3;
                        } else {
                            step = 2;
                        }
                    } else {
                        step = 1;
                    }
                    int[] pair = new int[step + 1];
                    for (int k = i; k <= i + step; k++) {
                        pair[k - i] = listCards[k];
                    }
                    if (step >= 1) {
                        CardSet pairSet = new CardSet(pair, CardSet.PAIR);
                        listCardSets.add(pairSet);
                    }
                    j = numberCards;
                    i = i + step;
                }
            }
        }
    }

    private static void extractSpecialPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13
                        || (listCards[i] % 13 == listCards[j] % 13 && listCards[i] / 13 < listCards[j] / 13)) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }
        //tim phom ngang
        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    if (j < numberCards - 1 && cardId % 13 == listCards[j + 1] % 13) {
                        if (j < numberCards - 2 && cardId % 13 == listCards[j + 2] % 13) {
                            step = 3;
                        } else {
                            step = 2;
                        }
                    } else {
                        step = 1;
                    }
                    int[] pair = new int[step + 1];
                    for (int k = i; k <= i + step; k++) {
                        pair[k - i] = listCards[k];
                    }
                    if (step >= 1) {
                        CardSet pairSet = new CardSet(pair, CardSet.PAIR);
                        listCardSets.add(pairSet);
                    }
                    j = numberCards;
                    i = i + step;
                }
            }
        }
    }

    private static void swap(int i, int j, int[] listCards) {
        int temp = listCards[j];
        listCards[j] = listCards[i];
        listCards[i] = temp;
    }

    private static void printListCardId(int[] listCards) {
        int numberCard = listCards.length;
        Debug.d("");
        for (int i = 0; i < numberCard; i++) {
            System.out.print(Card.getName(listCards[i]) + ",");
        }
    }
}
